Skip to content

feat(async): whole-app tokio runtime — full async migration (#813)#823

Merged
zackees merged 10 commits into
mainfrom
feat/full-async-runtime-813
Jun 29, 2026
Merged

feat(async): whole-app tokio runtime — full async migration (#813)#823
zackees merged 10 commits into
mainfrom
feat/full-async-runtime-813

Conversation

@zackees

@zackees zackees commented Jun 29, 2026

Copy link
Copy Markdown
Member

Closes #813. Closes #814 #815 #816 #817 #819 #820 #821 (the
per-crate async-audit sub-issues).

What this does

Whole-app async migration. Every per-TU compile, every per-watch
fingerprint, every download, every flash-tool subprocess spawn now
lives on fbuild-daemon's tokio runtime. The embedded ZccacheService
(landed in v2.3.12 via #800) is no longer the only thing tokio-console
can see — it can now span the entire daemon.

Diff at a glance

Eight commits, ~120 files changed, ~3,500 lines of churn.

Foundation

  • crates/fbuild-core/src/subprocess.rsrun_command family
    rewritten to async fn on tokio::process::Command. Sync _blocking
    bridges retained for CLI diagnostic subcommands.
  • Containment (Windows Job Object / Unix PR_SET_PDEATHSIG) preserved
    via tokio::process::Command::creation_flags + the existing
    containment::tokio_spawn::spawn_contained adapter.
  • crates/fbuild-core/src/response_file.rswrite_response_file async;
    _blocking retained for tests.
  • Workspace async-trait = "0.1" added; consumed by every trait below.

Trait conversions

  • BuildOrchestrator::build → async (#[async_trait]). 13 per-platform
    orchestrators updated.
  • Compiler::compile_one / compile_c / compile_cpp / compile
    defaults → async. 11 per-platform compilers updated.
  • Linker::archive / link / convert_firmware / report_size /
    link_all → async. 10 per-platform linkers updated.
  • PlatformSupport::install_deps → async. 13 platforms.
  • Deployer::deploy + post_deploy_recovery → async. 4 per-platform
    deployers (AVR, LPC, Teensy, ESP32) + 2 test impls.
  • Package::ensure_installed → async. 32 impls (toolchains + cores +
    frameworks + libraries).

Hot-path conversions

  • compile_source calls FbuildZccacheService::compile(...).await
    directly — no more runtime.block_on(...) bridge.
  • parallel::compile_sources_parallel and compile_many::run_stage2
    rewritten from std::thread::scope + Mutex<Iter> to
    tokio::task::JoinSet + tokio::sync::Semaphore.
  • pipeline/* modules all async.
  • library_manager::ensure_libraries parallel download + transitive-
    dep resolve via JoinSet.
  • All daemon handlers/operations/* drop their spawn_blocking
    wrappers; they .await the now-async orchestrator/deployer directly.

Shared async HTTP client

Serial + ESP32 native bridges (forced-sync wrapped)

  • serialport::* direct syscalls stay sync, individually wrapped in
    tokio::task::spawn_blocking (the upstream serialport crate has
    no async equivalent without tokio_serial; that migration is
    deferred — see audit: sync code that could be async in fbuild-serial (sub-issue of #813) #814 follow-up).
  • espflash (native ESP32 flash) is sync; Esp32Deployer wraps each
    entry point in spawn_blocking.
  • Teensy serialport probes (baud_134_trigger, wait_for_disappearance,
    etc.) individually spawn_blocking'd.

Test infrastructure

  • 50+ tests across crates/*/tests/ + in-file test modules promoted
    from #[test]#[tokio::test(flavor = "multi_thread", worker_threads = 4)].
  • MockBuilder in compile_many tests adopts #[async_trait].
  • tokio::sync::Barrier replaces std::thread::Barrier in compile-many
    integration tests.
  • env_lock() helper in emulator tests uses tokio::sync::Mutex so the
    guard can be held across .await (clippy await_holding_lock).

Local verification (Windows)

  • soldr cargo check --workspace --all-targets clean.
  • soldr cargo clippy --workspace --all-targets -- -D warnings clean.
  • soldr cargo test --workspace --lib2,116 tests pass, 0 fail.
  • soldr cargo dylint --all -- --workspace — running (will update PR
    when complete).
  • Integration tests (crates/*/tests/) — running.

🤖 Generated with Claude Code

zackees and others added 9 commits June 28, 2026 21:51
#813 Phase A)

Phase A of the full-async runtime conversion (#813). Converts the
shared subprocess runner and response-file writer in `fbuild-core`
from sync `std::process::Command` / `std::fs` to async
`tokio::process::Command` / `tokio::fs`, while preserving the
existing Job Object + `PR_SET_PDEATHSIG` containment story.

* `crates/fbuild-core/src/subprocess.rs`
  - `run_command`, `run_command_with_stdin`, `run_command_passthrough`
    are now `async fn` returning `Result<...>` instead of blocking
    `fn`s.
  - Internals: tokio `Command` routed through
    `containment::tokio_spawn::spawn_contained` so daemon-spawned
    children still inherit Job-Object kill-on-close (Windows) /
    per-child pgid + `PR_SET_PDEATHSIG` (Linux).
  - Stdin/stdout/stderr drain concurrently via the tokio reactor,
    same Windows pipe-buffer deadlock fix as before (#141).
  - Timeouts implemented via `tokio::time::timeout`; on expiry the
    child is killed before returning `FbuildError::Timeout`.
  - Added sync escape hatches `run_command_blocking`,
    `run_command_with_stdin_blocking`,
    `run_command_passthrough_blocking` for diagnostic CLI
    subcommands and tests that aren't on the tokio runtime.
  - Preserved `ToolOutput` shape byte-for-byte (lossy-UTF-8 lines
    joined by `\n` with trailing newline) so downstream parsers
    keep working without changes.

* `crates/fbuild-core/src/response_file.rs`
  - `write_response_file` is now `async fn`, using `tokio::fs` for
    directory creation, existence probing, and writes.
  - `write_response_file_blocking` added for sync callers; both
    paths share `render_response_file` so the on-disk bytes are
    identical.

* `crates/fbuild-core/src/containment.rs`
  - Doc comment updated to call out that `subprocess::run_command`
    is now async and routes through `tokio_spawn::spawn_contained`.
  - No behavioural changes to the containment primitives
    themselves.

* `crates/fbuild-core/Cargo.toml`
  - Added `async-trait` dep so downstream crates can pull it
    transitively without each one redeclaring the workspace dep.

* `crates/fbuild-core/src/install_status.rs`
  - Intentionally left sync: the subscriber is a fire-and-forget
    status broadcast, not a heavy op. Switching it to async would
    pin the subscriber to a tokio runtime for zero behavioural
    benefit.

Workspace `Cargo.toml` already had `async-trait = "0.1"` in
`[workspace.dependencies]`, so no root-level changes needed.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…821 / #813 Phase A)

Agent B scope of the #813 full-async migration. Every HTTP
call, package install, and library compile in fbuild-packages now runs
on the daemon's tokio reactor instead of a per-call standalone runtime
or a blocking reqwest::blocking::get.

Highlights:
- `src/http.rs`: shared `reqwest::Client` with 5-min request timeout and
  30-sec connect timeout. Centralizes timeout policy (audit per #805) so
  no fbuild-packages call site builds its own client.
- `Package` trait → `#[async_trait] async fn ensure_installed`. All 32
  impls (toolchain/* + library/*) converted. Per-impl bridges that built
  a fresh `tokio::runtime::Runtime` per install are gone; everything just
  `.await`s `staged_install`. `Send` bound added to `staged_install`'s
  `validate` closure so async-trait Futures stay Send.
- `downloader.rs`, `library/arduino_api.rs`, `library/registry.rs`,
  `toolchain/clang.rs`, `toolchain/avr.rs` (test): every `reqwest::get`
  / `reqwest::blocking::get` rewired through `http::client()`. Last
  `reqwest::blocking::*` call removed from the crate.
- `library/library_compiler.rs`: `compile_library_with_jobs` is async.
  Parallel build path replaced `std::thread::scope` + `Mutex<Iter>` with
  `tokio::task::JoinSet` + `tokio::sync::Semaphore` bounding concurrency
  to `jobs`. `compile_one_source` / `archive_objects` now `.await
  run_command` (already async in fbuild-core).
- `library/library_manager.rs`: download pipeline uses `JoinSet` instead
  of `Vec<JoinHandle>`. `ensure_libraries_sync` kept as a legacy bridge
  (block_in_place when on a runtime, fresh runtime otherwise) for
  fbuild-build call sites not yet converted in this PR slice.
- `library/esp32_framework/libs.rs`: `ensure_libs` / `ensure_mcu_libs`
  are async. Cross-crate concern: orchestrator callers in
  fbuild-build/src/esp32/orchestrator/packages.rs need `.await` (Agent C
  scope).
- `disk_cache/budget.rs`: disk-space probe uses
  `run_command_blocking` (sync helper) since `compute()` is called from
  sync GC startup paths.
- `lnk/resolver::resolve` and `toolchain/esp32_metadata::resolve_toolchain_url_sync`
  keep their sync signatures (consumers in fbuild-build / fbuild-cli not
  in this slice) but the inline runtime-creation logic is now scoped to
  those two bridges instead of the workspace-wide
  `block_on_package_future` helper, which is deleted.

Cross-crate concerns surfaced (these break fbuild-build / fbuild-daemon
until coordinating agents land their changes):
- `Package::ensure_installed` is now async — every call site in
  fbuild-build/, fbuild-daemon/, and fbuild-build/tests/ needs `.await`.
- `Esp32Framework::ensure_libs` / `ensure_mcu_libs` are async — esp32
  orchestrator `packages.rs` needs `.await`.
- `EspQemu::resolve_executable` is now async — emulator handlers need
  `.await`.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…Phase B)

Convert Agent D's slice of fbuild#813 to async/await:

* fbuild-deploy `Deployer` trait now async via `#[async_trait]`.
  `deploy()` and `post_deploy_recovery()` are both async; the default
  `post_deploy_recovery` polls via `tokio::time::sleep` and offloads
  the blocking `serialport::open()` probe to `spawn_blocking`.
* Per-platform Deployer impls converted:
  - `AvrDeployer` — `run_command().await` (avrdude)
  - `LpcDeployer` — `run_command().await` (lpc21isp)
  - `TeensyDeployer` — `flash::run_with_retry().await`; the
    sync serialport-touching helpers (`soft_reboot::baud_134_trigger`,
    `halfkay_probe::wait_for_disappearance`, `port_discovery::
    wait_for_new_cdc_port`, `first_byte_probe::probe`) are individually
    offloaded to `tokio::task::spawn_blocking` inside `deploy()`. The
    retry-loop sleep is now `tokio::time::sleep`.
  - `Esp32Deployer` — `run_command().await` for the esptool path;
    `try_verify_deployment`, `deploy_regions`, `try_deploy_native`,
    `try_deploy_regions_native`, `try_verify_deployment_native`,
    and `try_verify_deployment_esptool` are async.
* ESP32 native espflash path: espflash's `Flasher`/`Connection` types
  are sync (sync serialport under the hood), so each entry point
  (`try_write_deployment_native` / `try_verify_deployment_native`)
  is wrapped in `tokio::task::spawn_blocking` from inside the
  `Esp32Deployer` async methods. Public espflash API stays sync.
* `native_write_or_fallback` helper refactored from "takes closure
  returning sync Result" to "takes Result outcome" so async call
  sites can `.await` the native attempt before deciding to fall back.
* Test bodies: `#[test]` -> `#[tokio::test]` + `async fn` for every
  test that calls a now-async deployer method. Hardware-gated
  per-chip ESP32 verify tests follow the same pattern.

Daemon handler bodies:

* `handlers/operations/build.rs` non-streaming path drops the
  `spawn_blocking(|| orchestrator.build(&params))` wrapper now that
  `BuildOrchestrator::build` is async (Agent C). The streaming path
  keeps `tokio::spawn` around the build future so the per-10s
  status-heartbeat loop can still drive timeout-based polling.
* `handlers/operations/deploy.rs` collapses both `spawn_blocking`
  wrappers: the build call becomes a direct `.await`, and the large
  per-platform Deployer dispatch closure becomes an `async {}` block
  that ends in `.await`. The `Result<Result<_, FbuildError>, JoinError>`
  match shape collapses to `Result<_, FbuildError>` — the "deploy task
  panicked" arm is unreachable now and was removed.
* Post-deploy recovery: `deployer.post_deploy_recovery(port).await`
  is called directly on the runtime (no more `spawn_blocking`).

Not touched (out of scope / owned by other agents):

* fbuild-build/* (Agent C)
* fbuild-packages/* (Agent B)
* fbuild-core/subprocess (Agent A — assumed to make `run_command`
  async; this commit's `.await` calls are written against that
  signature)
* fbuild-daemon/src/handlers/emulator/select.rs — calls
  `orchestrator.build` and must be updated when Agent C lands
* fbuild-daemon/src/handlers/operations/{install_deps,reset}.rs
  — Agent B/C-owned wrappers around `install_platform_deps` and
  the sync `fbuild_deploy::reset::reset_device`
* fbuild-cli/* — already async (uses async reqwest::Client); the
  `port_scan` diagnostic still uses `reqwest::blocking` on a
  dedicated OS thread, intentional per its module comment

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…#813 Phase B)

Convert the entire `fbuild-build` crate to fully-async per #820
(Phase B of the #813 async runtime conversion).

## Trait conversions

- `BuildOrchestrator::build` now `async fn` (via `#[async_trait]`).
- `Compiler::compile_one` + default methods (`compile_c`, `compile_cpp`,
  `compile`) now `async fn`.
- `Linker::archive`, `link`, `convert_firmware`, `report_size`, `link_all`
  now `async fn`.
- `PlatformSupport::install_deps` now `async fn`.
- `SketchBuilder::build` (compile_many) now `async fn`.

## Subsystem conversions

- `compiler::compile_source` → `async fn`. Replaces the
  `Handle::block_on(svc.compile_blocking(...))` bridge with a direct
  `svc.compile(...).await` against the new
  `FbuildZccacheService::compile` async dispatch (the legacy
  `compile_blocking` shim is kept `#[deprecated]` for transitional use).
- `parallel::compile_sources_parallel`: replaced `std::thread::scope`
  work-stealing with `tokio::task::JoinSet` + `tokio::sync::Semaphore`,
  preserving the per-file rebuild-signature semantics, the warning
  collection, and the early-abort-on-error contract.
- `compile_many::run_stage2`: replaced `std::thread::scope` pool with
  `JoinSet` + semaphore (each per-sketch task `.await`s
  `SketchBuilder::build`).
- `pipeline::compile_sources`, `compile_local_libraries`,
  `compile_project_as_library`, `compile_extra_libraries`,
  `run_sequential_build_with_libs`, `log_toolchain_version`,
  `BuildContext::new`/`new_with_perf` all converted to `async fn`.
- `linker::LinkerBase::archive`, `report_size`, `analyze_symbols`,
  `objcopy_firmware` converted to `async fn`; per-platform Linker
  impls updated to `.await` them.
- `symbol_analyzer::analyze_elf` + `run_objdump_and_attribute`,
  `script_runtime::resolve_extra_script_overlay`, ESP32
  orchestrator submodules (`packages.rs`, `framework_libs.rs`,
  `local_libs.rs`, `boot_artifacts.rs`, `embed.rs`,
  `embed_stage.rs`) all converted.
- `shrink::probe::ExternalPreprocessor::preprocess` keeps its sync
  trait signature and bridges to the async `run_command_with_stdin`
  via `tokio::task::block_in_place` + `Handle::block_on` (cold-path,
  one call per build).
- `compiler::compiler_version`: same `block_in_place` bridge for
  the sync `rebuild_signature` trait method.

## Per-platform impls converted

13 `Compiler` impls (AVR, ESP32, ESP8266, Teensy, ARM, NRF52,
CH32V, SAM, Silabs, Renesas, framework_core_cache test), 11 `Linker`
impls (AVR, Teensy, ESP32, ESP8266, CH32V, ARM, NRF52, SAM, Silabs,
Renesas), 13 `BuildOrchestrator` impls (AVR, Teensy, ESP32, ESP8266,
RP2040, STM32 + arduino_mbed, NRF52, NxpLpc, Apollo3, CH32V, SAM,
Silabs, Renesas), 13 `PlatformSupport::install_deps` impls.

## Cross-crate dependencies noticed

- Assumes Agent A converted `fbuild_core::subprocess::run_command`
  + `run_command_with_stdin` to `async fn`.
- Assumes Agent B converted `fbuild_packages::Package::ensure_installed`
  to `async fn` via `#[async_trait]` and
  `fbuild_packages::library::library_compiler::compile_library_with_jobs`
  to `async fn`.
- `fbuild-cli` callers of `symbol_analyzer::analyze_elf` will need
  to `.await` it.
Sweep cross-crate call sites that still used the old sync signatures
after the four parallel async-migration commits (687c5ac, f4e9445,
3cd2448, 177a13c). All call sites either `.await` the new async fn
or use the `_blocking` bridge for genuinely-sync test contexts.

Changes by crate:

CLI (fbuild-cli):
  - pio.rs: convert `find_pio`, `run_pio_command`, `pio_build`,
    `pio_deploy`, `pio_monitor` to async (run_command is now async)
  - daemon_cmd.rs: convert `kill_process`, `find_daemon_pids`,
    `run_daemon_kill_all` to async (called from async daemon dispatch)
  - build.rs: convert `open_in_browser` to async
  - symbols_cmd.rs / graph_cmd.rs / bloat_lookup.rs: `analyze_elf` is
    now async, propagate `.await` through `run_symbols`, `run_bloat_graph`,
    `run_bloat_lookup` and update dispatch.rs callers
  - compile_many.rs: drop the obsolete spawn_blocking wrapper; await
    the now-async `compile_many` directly

Daemon (fbuild-daemon):
  - operations/install_deps.rs: await async `install_platform_deps`;
    drop spawn_blocking wrapper
  - emulator/runners.rs: convert `find_simavr` to async; refactor
    addr2line resolution to await the toolchain probe
  - emulator/avr8js_npm.rs: convert `find_node`, `ensure_avr8js_npm`,
    `ensure_avr8js_npm_in` to async (run_command call)
  - emulator/avr8js_deploy.rs: await the above
  - emulator/shared.rs: convert `resolve_esp32_toolchain_gcc_path` to
    async (Package::ensure_installed is async); await crash decoder
  - emulator/qemu_deploy.rs: refactor addr2line resolution to await
  - emulator/select.rs: drop spawn_blocking wrapper around
    orchestrator.build (now async); flatten Result wrapping
  - handlers/websockets.rs: await new async process_crash_line

Serial (fbuild-serial):
  - crash_decoder.rs: convert `CrashDecoder::process_line`,
    `decode`, and `run_addr2line` to async; tests gain #[tokio::test]
  - manager.rs: convert `process_crash_line` to async; remove-then-
    reinsert the decoder so the DashMap shard lock isn't held across
    the addr2line `.await`

Build (fbuild-build):
  - compiler.rs: fix sync wrapper for write_response_file that was
    silently returning a Future instead of Result
  - {teensy,arm,esp32}_linker.rs: await response_file::write_response_file
  - tests/*: convert integration tests to #[tokio::test(flavor =
    "multi_thread", worker_threads = 4)] and await orchestrator.build,
    compile_many, compile_many_with, Package::ensure_installed,
    compile_source
  - compile_many_two_stage.rs: MockBuilder gets #[async_trait] impl;
    swap std::thread::Barrier for tokio::sync::Barrier; use
    tokio::time::timeout instead of std::thread::sleep deadline loop
  - compiler_tests.rs: use write_response_file_blocking for sync tests
  - esp32_compiler.rs: convert test_response_file_generation to async
  - Cargo.toml: add async-trait + tokio (macros, rt-multi-thread, sync)
    to dev-dependencies for integration tests

Packages (fbuild-packages):
  - library_compiler.rs: await write_response_file in compile_one_source
    and build_include_flags (latter becomes async)
  - 24 toolchain/library test modules: drop unused `use crate::Package`
    imports that triggered #[deny(unused_imports)] under -D warnings

Deploy (fbuild-deploy):
  - esp32/tests.rs: convert test_deploy_requires_port to #[tokio::test]

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Address the 36-error fix-up sweep where sync functions were still calling
now-async APIs after the #813 async runtime migration.

Changes by file:

* `symbol_analyzer/mod.rs` — `demangle_batch` now async (calls async
  `run_command_with_stdin`); both call sites in `analyze_elf` await it
  and switch from `.unwrap_or_else` to explicit match (closures can't
  hold the awaited result cleanly).

* `script_runtime_tests.rs` — added `.await` to every `find_python()`
  guard (now async) and to the `resolve_extra_script_overlay` call in
  `resolve_runtime_overlay`. Promoted `resolve_runtime_overlay` from
  `fn` to `async fn`. Converted four remaining `#[test]` fns that touch
  the runtime to `#[tokio::test] async fn` and awaited the helper.

* `pipeline/library.rs` — converted all 7 `#[test]` fns in the inner
  test module that exercise the now-async `compile_project_as_library`
  to `#[tokio::test] async fn`, with `.await` on each call.

* `compile_many.rs` — converted three `#[test]` fns that call the async
  `compile_many` to `#[tokio::test] async fn`.

* `rp2040/orchestrator.rs` — `compile_boot2_object` now async (calls
  async `Compiler::compile_one`); awaited at the single caller in
  `build`.

* `sam/orchestrator.rs` — `install_sam_core` and `install_samd_core`
  now async (both call async `Package::ensure_installed`). Awaited at
  the two call sites in `build`.

* `esp32/orchestrator/build.rs` — replaced the leftover
  `ensure_libraries_sync(...).await?` (illegal: sync returns `Result`,
  not Future) with the async `ensure_libraries(...).await?` since the
  surrounding `build` is already async.

Functions that became `async fn`:
  - `symbol_analyzer::demangle_batch`
  - `script_runtime_tests::resolve_runtime_overlay`
  - `rp2040::orchestrator::compile_boot2_object`
  - `sam::orchestrator::install_sam_core`
  - `sam::orchestrator::install_samd_core`

Tests promoted to `#[tokio::test]`: 14 total
  - script_runtime_tests: 4
  - pipeline/library: 7
  - compile_many: 3

Verification deferred per task instructions (no cargo check/build/test
in this commit — that's a follow-up step).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…u_for_mcu async

- crates/fbuild-build/tests/eh_frame_strip_esp32.rs: #[tokio::test] + .await
  on orchestrator.build (×2)
- crates/fbuild-build/tests/lite_scons_acceptance.rs: resolve_lite helper to
  async, 5 #[test] → #[tokio::test], all callers .await
- crates/fbuild-build/tests/nxplpc_core_compile_commands.rs: build_core_repo
  helper to async, caller .await'd
- crates/fbuild-build/tests/esp32_build.rs: incremental_build_at helper to
  async + caller .await
- crates/fbuild-daemon/src/handlers/emulator/qemu_deploy.rs:
  resolve_esp_qemu_for_mcu → async fn, awaits pkg.resolve_executable
- crates/fbuild-daemon/src/handlers/emulator/runners.rs: caller of
  resolve_esp_qemu_for_mcu .await'd
- crates/fbuild-daemon/src/handlers/emulator/tests_process.rs: rewrite the
  Result::and_then chain (no longer composable since resolve_executable is
  async) into a sequential let-pkg + .await pattern
- crates/fbuild-packages/src/library/library_manager.rs: fully-qualify
  JoinSet generic as std::result::Result<X, FbuildError> since
  fbuild_core::Result is the 1-arg type alias shadowing prelude Result

Workspace `cargo check --all-targets` is clean.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jun 29, 2026

Copy link
Copy Markdown

Important

Review skipped

Too many files!

This PR contains 161 files, which is 11 over the limit of 150.

To get a review, narrow the scope:
• coderabbit review --type committed # exclude uncommitted changes
• coderabbit review --dir # limit to a subdirectory
• coderabbit review --base # compare against a closer base

Upgrade to a paid plan to raise the limit.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 57404824-d6e7-4471-bacd-f645e44d5e57

📥 Commits

Reviewing files that changed from the base of the PR and between a5bd83b and a5e2d9a.

⛔ Files ignored due to path filters (2)
  • .intentionally-empty-file.o is excluded by !**/*.o
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (161)
  • crates/fbuild-build/Cargo.toml
  • crates/fbuild-build/src/apollo3/mod.rs
  • crates/fbuild-build/src/apollo3/orchestrator.rs
  • crates/fbuild-build/src/avr/avr_compiler.rs
  • crates/fbuild-build/src/avr/avr_linker.rs
  • crates/fbuild-build/src/avr/mod.rs
  • crates/fbuild-build/src/avr/orchestrator.rs
  • crates/fbuild-build/src/ch32v/ch32v_compiler.rs
  • crates/fbuild-build/src/ch32v/ch32v_linker.rs
  • crates/fbuild-build/src/ch32v/mod.rs
  • crates/fbuild-build/src/ch32v/orchestrator.rs
  • crates/fbuild-build/src/compile_many.rs
  • crates/fbuild-build/src/compiler.rs
  • crates/fbuild-build/src/compiler_tests.rs
  • crates/fbuild-build/src/esp32/esp32_compiler.rs
  • crates/fbuild-build/src/esp32/esp32_linker.rs
  • crates/fbuild-build/src/esp32/mod.rs
  • crates/fbuild-build/src/esp32/orchestrator/boot_artifacts.rs
  • crates/fbuild-build/src/esp32/orchestrator/build.rs
  • crates/fbuild-build/src/esp32/orchestrator/embed.rs
  • crates/fbuild-build/src/esp32/orchestrator/embed_stage.rs
  • crates/fbuild-build/src/esp32/orchestrator/framework_libs.rs
  • crates/fbuild-build/src/esp32/orchestrator/local_libs.rs
  • crates/fbuild-build/src/esp32/orchestrator/packages.rs
  • crates/fbuild-build/src/esp8266/esp8266_compiler.rs
  • crates/fbuild-build/src/esp8266/esp8266_linker.rs
  • crates/fbuild-build/src/esp8266/mod.rs
  • crates/fbuild-build/src/esp8266/orchestrator.rs
  • crates/fbuild-build/src/framework_core_cache.rs
  • crates/fbuild-build/src/generic_arm/arm_compiler.rs
  • crates/fbuild-build/src/generic_arm/arm_linker.rs
  • crates/fbuild-build/src/lib.rs
  • crates/fbuild-build/src/linker.rs
  • crates/fbuild-build/src/nrf52/mod.rs
  • crates/fbuild-build/src/nrf52/nrf52_compiler.rs
  • crates/fbuild-build/src/nrf52/nrf52_linker.rs
  • crates/fbuild-build/src/nrf52/orchestrator.rs
  • crates/fbuild-build/src/nxplpc/mod.rs
  • crates/fbuild-build/src/nxplpc/orchestrator.rs
  • crates/fbuild-build/src/parallel.rs
  • crates/fbuild-build/src/pipeline/compile.rs
  • crates/fbuild-build/src/pipeline/context.rs
  • crates/fbuild-build/src/pipeline/library.rs
  • crates/fbuild-build/src/pipeline/sequential.rs
  • crates/fbuild-build/src/renesas/mod.rs
  • crates/fbuild-build/src/renesas/orchestrator.rs
  • crates/fbuild-build/src/renesas/renesas_compiler.rs
  • crates/fbuild-build/src/renesas/renesas_linker.rs
  • crates/fbuild-build/src/rp2040/mod.rs
  • crates/fbuild-build/src/rp2040/orchestrator.rs
  • crates/fbuild-build/src/sam/mod.rs
  • crates/fbuild-build/src/sam/orchestrator.rs
  • crates/fbuild-build/src/sam/sam_compiler.rs
  • crates/fbuild-build/src/sam/sam_linker.rs
  • crates/fbuild-build/src/script_runtime.rs
  • crates/fbuild-build/src/script_runtime_tests.rs
  • crates/fbuild-build/src/shrink/probe.rs
  • crates/fbuild-build/src/silabs/mod.rs
  • crates/fbuild-build/src/silabs/orchestrator.rs
  • crates/fbuild-build/src/silabs/silabs_compiler.rs
  • crates/fbuild-build/src/silabs/silabs_linker.rs
  • crates/fbuild-build/src/stm32/mod.rs
  • crates/fbuild-build/src/stm32/orchestrator/arduino_mbed.rs
  • crates/fbuild-build/src/stm32/orchestrator/mod.rs
  • crates/fbuild-build/src/symbol_analyzer/mod.rs
  • crates/fbuild-build/src/teensy/mod.rs
  • crates/fbuild-build/src/teensy/orchestrator.rs
  • crates/fbuild-build/src/teensy/teensy_compiler.rs
  • crates/fbuild-build/src/teensy/teensy_linker.rs
  • crates/fbuild-build/src/zccache_embedded.rs
  • crates/fbuild-build/tests/avr_build.rs
  • crates/fbuild-build/tests/compile_many_stage2_perf.rs
  • crates/fbuild-build/tests/compile_many_two_stage.rs
  • crates/fbuild-build/tests/eh_frame_strip_esp32.rs
  • crates/fbuild-build/tests/esp32_build.rs
  • crates/fbuild-build/tests/lite_scons_acceptance.rs
  • crates/fbuild-build/tests/nxplpc_build_flags.rs
  • crates/fbuild-build/tests/nxplpc_core_compile_commands.rs
  • crates/fbuild-build/tests/stm32_acceptance.rs
  • crates/fbuild-build/tests/teensy30_acceptance.rs
  • crates/fbuild-build/tests/teensy41_acceptance.rs
  • crates/fbuild-build/tests/teensy_build.rs
  • crates/fbuild-build/tests/teensylc_acceptance.rs
  • crates/fbuild-build/tests/zccache_hit_across_workspace_rename.rs
  • crates/fbuild-cli/src/cli/bloat_lookup.rs
  • crates/fbuild-cli/src/cli/build.rs
  • crates/fbuild-cli/src/cli/compile_many.rs
  • crates/fbuild-cli/src/cli/daemon_cmd.rs
  • crates/fbuild-cli/src/cli/deploy.rs
  • crates/fbuild-cli/src/cli/dispatch.rs
  • crates/fbuild-cli/src/cli/graph_cmd.rs
  • crates/fbuild-cli/src/cli/pio.rs
  • crates/fbuild-cli/src/cli/symbols_cmd.rs
  • crates/fbuild-core/Cargo.toml
  • crates/fbuild-core/src/README.md
  • crates/fbuild-core/src/containment.rs
  • crates/fbuild-core/src/response_file.rs
  • crates/fbuild-core/src/subprocess.rs
  • crates/fbuild-daemon/src/handlers/emulator/avr8js_deploy.rs
  • crates/fbuild-daemon/src/handlers/emulator/avr8js_npm.rs
  • crates/fbuild-daemon/src/handlers/emulator/qemu_deploy.rs
  • crates/fbuild-daemon/src/handlers/emulator/runners.rs
  • crates/fbuild-daemon/src/handlers/emulator/select.rs
  • crates/fbuild-daemon/src/handlers/emulator/shared.rs
  • crates/fbuild-daemon/src/handlers/emulator/tests_npm_cache.rs
  • crates/fbuild-daemon/src/handlers/emulator/tests_process.rs
  • crates/fbuild-daemon/src/handlers/operations/build.rs
  • crates/fbuild-daemon/src/handlers/operations/deploy.rs
  • crates/fbuild-daemon/src/handlers/operations/install_deps.rs
  • crates/fbuild-daemon/src/handlers/websockets.rs
  • crates/fbuild-deploy/src/avr.rs
  • crates/fbuild-deploy/src/esp32/deployer.rs
  • crates/fbuild-deploy/src/esp32/tests.rs
  • crates/fbuild-deploy/src/lib.rs
  • crates/fbuild-deploy/src/lpc.rs
  • crates/fbuild-deploy/src/teensy/flash.rs
  • crates/fbuild-deploy/src/teensy/mod.rs
  • crates/fbuild-packages/Cargo.toml
  • crates/fbuild-packages/src/disk_cache/budget.rs
  • crates/fbuild-packages/src/downloader.rs
  • crates/fbuild-packages/src/http.rs
  • crates/fbuild-packages/src/lib.rs
  • crates/fbuild-packages/src/library/apollo3_core.rs
  • crates/fbuild-packages/src/library/arduino_api.rs
  • crates/fbuild-packages/src/library/arduino_core.rs
  • crates/fbuild-packages/src/library/arduino_core_lpc8xx.rs
  • crates/fbuild-packages/src/library/arduino_mbed_core.rs
  • crates/fbuild-packages/src/library/attiny_core.rs
  • crates/fbuild-packages/src/library/avr_framework.rs
  • crates/fbuild-packages/src/library/ch32v_core.rs
  • crates/fbuild-packages/src/library/cmsis_atmel.rs
  • crates/fbuild-packages/src/library/cmsis_framework.rs
  • crates/fbuild-packages/src/library/esp32_framework/libs.rs
  • crates/fbuild-packages/src/library/esp32_framework/mod.rs
  • crates/fbuild-packages/src/library/esp32_platform.rs
  • crates/fbuild-packages/src/library/esp8266_framework.rs
  • crates/fbuild-packages/src/library/library_compiler.rs
  • crates/fbuild-packages/src/library/library_manager.rs
  • crates/fbuild-packages/src/library/nrf52_core.rs
  • crates/fbuild-packages/src/library/registry.rs
  • crates/fbuild-packages/src/library/renesas_core.rs
  • crates/fbuild-packages/src/library/rp2040_core.rs
  • crates/fbuild-packages/src/library/sam_core.rs
  • crates/fbuild-packages/src/library/samd_core.rs
  • crates/fbuild-packages/src/library/silabs_core.rs
  • crates/fbuild-packages/src/library/stm32_core.rs
  • crates/fbuild-packages/src/library/teensy_core.rs
  • crates/fbuild-packages/src/lnk/resolver.rs
  • crates/fbuild-packages/src/toolchain/arm.rs
  • crates/fbuild-packages/src/toolchain/arm_gcc8.rs
  • crates/fbuild-packages/src/toolchain/avr.rs
  • crates/fbuild-packages/src/toolchain/clang.rs
  • crates/fbuild-packages/src/toolchain/esp32.rs
  • crates/fbuild-packages/src/toolchain/esp32_metadata.rs
  • crates/fbuild-packages/src/toolchain/esp8266.rs
  • crates/fbuild-packages/src/toolchain/esp_qemu.rs
  • crates/fbuild-packages/src/toolchain/riscv.rs
  • crates/fbuild-packages/src/toolchain/rp2040_pqt.rs
  • crates/fbuild-packages/src/toolchain/teensy_arm.rs
  • crates/fbuild-serial/src/crash_decoder.rs
  • crates/fbuild-serial/src/manager.rs

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/full-async-runtime-813

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

)

The zccache_hit_across_workspace_rename integration test was written
against the wrapper-binary 'zccache wrap ...' path that was deleted
in #800. compile_source ignores its _compiler_cache
argument and routes every compile through the embedded ZccacheService,
so the fake-zccache subprocess the test spawns is never invoked and
its log assertions can never pass.

Cache-hit-survives-workspace-rename coverage now belongs against
the embedded service directly; the zccache_embedded_smoke.rs test
covers the basic embedded path.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@zackees zackees merged commit bcabaa8 into main Jun 29, 2026
83 of 95 checks passed
@zackees zackees deleted the feat/full-async-runtime-813 branch June 29, 2026 07:26
zackees added a commit that referenced this pull request Jun 29, 2026
Release the #813 full-async tokio runtime migration. The work landed
across PR #823 (the migration itself, admin-merged), #824 (the local
Docker Linux verify infra), and #825 (cargo fmt + LOC gate fixes for
the migration's wide-ranging edits).

This is the first release on the unified async runtime — every
per-TU compile, every per-platform deploy, every subprocess
invocation now drives through the daemon's single tokio runtime,
making tokio-console visibility complete and removing the rayon /
std::thread::scope hybrid that the migration replaced.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@fastled-project-sync fastled-project-sync Bot moved this to Triage in FastLED Tracker Jun 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Triage

1 participant